package com.wframe.project.jnd.util;

import com.frame.database.JdataBean;
import com.wframe.project.jnd.entity.MoneyOffItem;
import com.wframe.project.jnd.entity.MoneyOffPromotion;
import com.wframe.project.jnd.entity.Promotion;
import com.wframe.project.jnd.vo.CartBean;
import com.wframe.project.jnd.vo.CartItem;
import com.wframe.project.jnd.vo.CartProductVO;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

/**
 * Created by lwb on 2017/6/5.
 */
@Component
public class MoneyOffPromotionBuilder extends ComplexPromotionsBuilder {
    @Override
    public Promotion build(String promotionId) {
        return promotionService.findMoneyOff(promotionId);
    }

    public CartBean getCartProducts(String userid, String promotionId, List<CartItem> prices, int platform, Map<String, Integer> tempProductStock) {
        CartBean bean = new CartBean();
        Map<String, CartItem> map = new HashMap<>();
        for (CartItem item : prices) {
            map.put(String.valueOf(item.getProductid()), item);
        }

        //处理有其他促销的情况
        Map<String, Object> process = otherPromotionProcess(userid, map, platform, tempProductStock);
        List<CartProductVO> products = (List<CartProductVO>) process.get("products");
        BigDecimal totalPrice = (BigDecimal) process.get("totalPrice");

        //满减促销前的价格
        bean.setMinuendPrice(totalPrice);

        MoneyOffPromotion moneyOff = (MoneyOffPromotion) promotionService.findMoneyOff(promotionId);
        List<MoneyOffItem> items = moneyOff.getItems();
        bean.setItems(items);

        MoneyOffPromotionHandlerChain chain = new MoneyOffPromotionHandlerChain(items);
        //如果满足条件，满足条件的满减
        //如果没有满足条件，将会触发的满减
        MoneyOffItem item = chain.handle(totalPrice);
        //满减金额
        bean.setStandardMoney(item.getOffMoney());
        //优惠金额
        BigDecimal discountMoney = item.getDiscountMoney();
        //满减折扣
        Double discountRate = item.getDiscountRate();
        BigDecimal rate = null;
        if (item.isAvailable()) {
            //满足条件
            bean.setAvailable(true);
            if (Objects.nonNull(discountRate)) {
                rate = BigDecimal.valueOf(discountRate).divide(BigDecimal.valueOf(10));
                discountMoney = totalPrice.subtract(totalPrice.multiply(rate));
            }
            totalPrice = totalPrice.subtract(discountMoney);
        }
        bean.setDiscountMoney(discountMoney);
        bean.setDiscountRate(discountRate == null ? null : BigDecimal.valueOf(discountRate));

        bean.setTotalPrice(totalPrice);
        bean.setProducts(products);
        bean.setPromotionId(promotionId);
        return bean;
    }

    @Override
    public CartBean process(Map.Entry<String, List<JdataBean>> entry, Map<String, Integer> tempProductStock) throws CloneNotSupportedException {
        String promotionId = entry.getKey();
        CartBean bean = new CartBean();

        List<CartProductVO> products = new ArrayList<>();
        BigDecimal totalPrice = BigDecimal.ZERO;
        for (JdataBean item : entry.getValue()) {
            CartProductVO productVO = otherPromotionProcess(item, tempProductStock);
            products.addAll(addProduct(productVO));

            List<String> promotionIds = productVO.getPromotionIds();
            promotionIds.add(promotionId);
            //商品参加的所有促销
            productVO.setPromotionIds(promotionIds);
            totalPrice = totalPrice.add(productVO.getTotalPrice());
        }
        //满减促销前的价格
        bean.setMinuendPrice(totalPrice);

        MoneyOffPromotion moneyOff = (MoneyOffPromotion) promotionService.findMoneyOff(promotionId);
        List<MoneyOffItem> moneyOffItems = moneyOff.getItems();
        bean.setItems(moneyOffItems);

        MoneyOffPromotionHandlerChain chain = new MoneyOffPromotionHandlerChain(moneyOffItems);
        //如果满足条件，满足条件的满减
        //如果没有满足条件，将会触发的满减
        MoneyOffItem item = chain.handle(totalPrice);
        //满减金额
        bean.setStandardMoney(item.getOffMoney());
        //优惠金额
        BigDecimal discountMoney = item.getDiscountMoney();
        //满减折扣
        Double discountRate = item.getDiscountRate();
        BigDecimal rate = null;
        if (item.isAvailable()) {
            //满足条件
            bean.setAvailable(true);
            if (Objects.nonNull(discountRate)) {
                rate = BigDecimal.valueOf(discountRate).divide(BigDecimal.valueOf(10));
                discountMoney = totalPrice.subtract(totalPrice.multiply(rate));
            }
            //分摊后剩余的优惠金额
            bean.setRestMoney(apportionedPrice(promotionId, products, rate, discountMoney, totalPrice));

            totalPrice = totalPrice.subtract(discountMoney);
        }
        bean.setDiscountMoney(discountMoney);
        bean.setDiscountRate(discountRate == null ? null : BigDecimal.valueOf(discountRate));

        bean.setTotalPrice(totalPrice);
        bean.setProducts(products);
        bean.setPromotionId(promotionId);
        return bean;
    }

    @Override
    public CartBean getData(String userid, String promotionId, List<CartItem> prices, int platform, Map<String, Integer> tempProductStock) throws Exception {
        CartBean bean = new CartBean();

        List<CartProductVO> products = new ArrayList<>();
        BigDecimal totalPrice = BigDecimal.ZERO;
        for (CartItem item : prices) {
            CartProductVO productVO = otherPromotionProcess(userid, item, promotionId, platform, tempProductStock);
            addProduct(products, promotionId, productVO);

            List<String> promotionIds = productVO.getPromotionIds();
            promotionIds.add(promotionId);
            //商品参加的所有促销
            productVO.setPromotionIds(promotionIds);

            if (item.isCheck()) {
                totalPrice = totalPrice.add(productVO.getTotalPrice());
            }
        }
        //满减促销前的价格
        bean.setMinuendPrice(totalPrice);

        MoneyOffPromotion moneyOff = (MoneyOffPromotion) promotionService.findMoneyOff(promotionId);
        List<MoneyOffItem> items = moneyOff.getItems();
        bean.setItems(items);

        MoneyOffPromotionHandlerChain chain = new MoneyOffPromotionHandlerChain(items);
        //如果满足条件，满足条件的满减
        //如果没有满足条件，将会触发的满减
        MoneyOffItem item = chain.handle(totalPrice);
        //满减金额
        bean.setStandardMoney(item.getOffMoney());
        //优惠金额
        BigDecimal discountMoney = item.getDiscountMoney();
        //满减折扣
        Double discountRate = item.getDiscountRate();
        BigDecimal rate = null;
        if (item.isAvailable()) {
            //满足条件
            bean.setAvailable(true);
            if (Objects.nonNull(discountRate)) {
                rate = BigDecimal.valueOf(discountRate).divide(BigDecimal.valueOf(10));
                discountMoney = totalPrice.subtract(totalPrice.multiply(rate));
            }
            //分摊后剩余的优惠金额
            bean.setRestMoney(apportionedPrice(promotionId, products, rate, discountMoney, totalPrice));

            totalPrice = totalPrice.subtract(discountMoney);
        }
        bean.setDiscountMoney(discountMoney);
        bean.setDiscountRate(discountRate == null ? null : BigDecimal.valueOf(discountRate));

        bean.setTotalPrice(totalPrice);
        bean.setProducts(products);
        bean.setPromotionId(promotionId);
        return bean;
    }

    private BigDecimal apportionedPrice(String promotionId, List<CartProductVO> products, BigDecimal rate, BigDecimal discountMoney, BigDecimal totalPrice) {
        boolean isRate = true;
        if (Objects.isNull(rate)) {
            isRate = false;
            rate = totalPrice.subtract(discountMoney).divide(totalPrice, 10, RoundingMode.HALF_UP);
        }

        BigDecimal countPrice = BigDecimal.ZERO;
        for (CartProductVO product : products) {
            if (!product.isGift()) {
                //订单项数量
                BigDecimal quantity = BigDecimal.valueOf(product.getBuyNum());
                //订单项价格
                BigDecimal unitPrice = product.getPrice().multiply(rate).setScale(2, RoundingMode.DOWN);
                //订单项总价格
                BigDecimal unitTotalPrice = unitPrice.multiply(quantity);

                product.setApportionedPrice(unitPrice);
                countPrice = countPrice.add(unitTotalPrice);
            }

            Map promotionAmount = product.getPromotionAmount();
            promotionAmount.put(promotionId, 1);
            product.setPromotionAmount(promotionAmount);
        }

        if (isRate) {
            return totalPrice.multiply(rate).subtract(countPrice);
        } else {
            return totalPrice.subtract(discountMoney).subtract(countPrice);
        }
    }

}
